home *** CD-ROM | disk | FTP | other *** search
/ Gigarom 1 / Gigarom Macintosh Archives (Quantum Leap)(CDRM1080320)(1993).iso / FILES / HYP / T-Z / Windoids.cpt / Windoid 1.7 / card_12396.txt < prev    next >
Text File  |  1989-04-19  |  9KB  |  150 lines

  1. -- card: 12396 from stack: in.7
  2. -- bmap block id: 12635
  3. -- flags: 0000
  4. -- background id: 10029
  5. -- name: 
  6.  
  7.  
  8. -- part contents for background part 11
  9. ----- text -----
  10. ‚Ä¢ PART 1
  11.  
  12. One of the most useful things a computer can do is look up an item in a dictionary.  Like a simple database, a dictionary is a table with two columns.
  13.  
  14. A script looks up a key in one column and reads off the value from the other column.  If the word dictionary does not seem to fit well (it does not contain any definitions), think of a Spanish-English dictionary.  There are many different situations in which a quick translation from one thing to another is useful.  If you are building an automatic table of contents for a stack, you might want to translate between titles of cards and card ID numbers.  In a spread sheet, you might want to translate names of cells into field numbers.
  15.  
  16. Suppose you have an address stack that contains formal names like 
  17. "Robert," "William," and "Elizabeth."  When you use the Find command, you really want to type nicknames like "Bob," "Bill," and "Liz."  Let‚Äôs write a script that translates the informal names you type into the formal names that appear in an address stack.
  18.  
  19. A simple way to build a dictionary is to make two lists.   The nicknames are separate words in one list, and the formal names are the corresponding words of the other.  The lists are stored in variables.  The lookup function steps through the words of the nickname list.  When it finds the name you asked for, it looks for the word in the same position in the formal name list.
  20.  
  21. First let's make a function that takes a key and two lists.  It looks the key up in the first list and returns a translation from the second:
  22.  
  23. function lookup key, listOfKeys, listOfAnswers
  24.   repeat with ii = 1 to the number of words of listOfKeys
  25.     if key = word ii of listOfKeys
  26.     then return word ii of listOfAnswers
  27.   end repeat
  28.   return key -- return the key if it is not in the list
  29. end lookup
  30.  
  31. Here is the way its used:
  32.  
  33.     put "Bob Bill Liz" into nickNames
  34.     put "Robert William Elizabeth" into formalNames
  35.     put lookup(word 1 of it, nickNames, formalNames) into word 1 of it 
  36.  
  37. Now, we need to hook this fragment of script to the Find command in our address stack.  Let‚Äôs intercept the Find command and translate the first word of the search key.  (Note that the Find command actually has two arguments.  The first is a number that keeps track of what kind of Find it is.  This number is inserted behind our backs, and all we have to do is know to give it a name.) This script will work in all versions of HyperCard.
  38.  
  39. on find dummy,key
  40.   -- dummy is used privately by HyperTalk
  41.   send "find" && quote & key & quote to HyperCard
  42.   if the result is "not found" then
  43.     put "Bob Bill Liz" into nickNames
  44.     put "Robert William Elizabeth" into formalNames
  45.     put key into newKey
  46.     put lookup(word 1 of newKey, nickNames, formalNames) into ¬¨
  47.     word 1 of newKey
  48.     if newKey is not key -- if word 1 was translated
  49.     then send "find" && quote & newKey & quote to HyperCard
  50.   end if
  51. end find
  52.  
  53. The script first sends the original Find command directly to HyperCard.  If the Find succeeds, do nothing further.  If the Find fails, then look up word 1 of the key and substitute it in.  If this substitution changes what we are looking for, then search on the new translated version.
  54.  
  55. Next, we‚Äôll refine this example to make it faster and more elegant.
  56. __________________________________________________________
  57.  
  58. PART 2            
  59.  
  60. ‚Ä¢ Let‚Äôs build a more powerful dictionary for converting a key into a value.  The key may contain more than one word, and there may be multiple keys (synonyms) for the same value.  We‚Äôll make the dictionary lookup go fast by using the "offset()" function to find the key in the dictionary.  Users can decide if the key should be matched completely, or if it need only match the beginning of an entry (like the Find command).
  61.  
  62. To allow multiple words in keys and values, we can‚Äôt use space as the separator between entries in the dictionary.  The characters { } and | are not used very much and are unlikely to appear in the things you want to put in your dictionary, so we‚Äôll use them as separators.  A dictionary entry with several keys and a value will be a single piece of text.  Every key has a { in before and after it, and the value has a | just before it and } just after it.  
  63.  
  64. Here is the entry that translates nicknames for Elizabeth:
  65.       {Liz{Beth{Betty{|Elizabeth}
  66.  
  67. Don't include spaces in a dictionary entries unless you want them to be part of a key or a value.  Each entry can be on a separate line if you wish.
  68.  
  69. Let's modify an address stack to translate from nicknames to formal names. We'll keep the dictionary in a global variable called "NickNames".  Here is the script that creates the dictonary when you enter the stack:
  70.  
  71. on openBackground
  72.   global NickNames
  73.   put "{Bob{|Robert}  {Bill{|William}  {Mike{|Michael} " &
  74.   "{Liz{Beth{Betty{|Elizabeth}   {Tom{|Thomas}" &
  75.   "{Jim{|James}  {Dave{|David}  {Joe{|Joseph}" into NickNames
  76. end openBackground
  77.  
  78. Next, let's build a function that does the actual work of looking up a key in the dictionary.  The "translate" function takes a key and a dictionary as arguments and returns the value for that key.  If the key is not in the dictionary, the function returns the key unchanged.
  79.  
  80. function translate key,dictionary,exact
  81.   put "{" & key into realKey  -- {Liz
  82.   if exact is empty           -- look for exact match
  83.   then put offset(realKey,dictionary) into index       -- loc of {Liz. . .
  84.   else put offset(realKey &"{",dictionary) into index  -- loc of {Liz{
  85.   
  86.   -- if the key wasn‚Äôt found, give back the original key
  87.   if index is 0 then return key     -- Liz
  88.   put char index to (index+200) of dictionary into local
  89.   --   {Liz{Beth{Betty{|Elizabeth}  {Tom{|Thomas...
  90.   put offset("|",local) into numStart     -- 17
  91.   put offset("}",local) into numEnd       -- 27
  92.   return char (numStart+1) to (numEnd-1) of local -- Elizabeth
  93. end translate
  94.  
  95. The first half of the translate script sets "index" to the location of the
  96. beginning of the key in the dictionary.  The second half pulls out a section of the dictionary into the variable "local" in order to work on it.  Currently, an entry in the dictionary can‚Äôt be longer than 200 characters 
  97. (for keys and value).  To allow longer entries, change the "200" to a bigger number.  The script finds the | at the beginning of the value part of the entry.  Then it finds the next } at the end of the entry.  It returns the characters from the beginning to the end of the value it found.
  98.  
  99. The third argument is optional.  If you leave it off, the first argument only has to match the beginning of a key in the dictionary (just like the Find command).  If you call translate with anything as the third argument, then the key will only be translated if it matches exactly.
  100.  
  101. Here are some sample calls: 
  102.     put translate("Betty", NickNames)
  103.     put translate("Mik", NickNames,"exact")
  104.  
  105. Mik is not translated to Michael in the second example because we specified an exact match.  Remember to put double-quotes around a 
  106. key if it has any spaces in it.  Put the translate function in your home script, and use it with all kinds of different dictionaries.
  107.  
  108. Here's how an address stack would use translate to convert nicknames to formal names for the Find command:
  109.  
  110. on find dummy,key
  111.   -- dummy is used privately by HyperTalk
  112.   send "find" && quote & key & quote to HyperCard
  113.   if the result is "not found" then
  114.     global NickNames
  115.     put key into newKey
  116.     repeat with jj = 1 to the number of words in key
  117.       put translate(word jj of key,NickNames) into newWord
  118.       put newWord into word jj of newKey
  119.     end repeat
  120.     
  121.     if newKey is key then beep
  122.     else
  123.       send "find" && quote & newKey & quote to HyperCard
  124.       if the result is "not found" then beep
  125.     end if
  126.   end if
  127. end find
  128.  
  129. This script first tries a normal HyperCard Find on the key.  If it is found, do nothing more.  If the key is not found, then for each word in the key, translate it through the dictionary NickNames and substitute in the translated word.  If the translation (newKey) is the same as the original 
  130. (key), then none of the words were in the dictionary.  Since the first search failed, beep and exit.  Otherwise, Find using the new key.  If it also can‚Äôt be found, then beep.  (Since we are calling Find from a script, it does not beep by itself.)
  131. Notice that the script always replaces a word in the key with its translated value.  Since words that are not in the dictionary come back from the translate function unchanged, this works.
  132.  
  133. Put the translate handler in your Home script to use from many stacks with many different dictionaries.  The modified Find handler goes in an address stack. It doesn't belong in the Home script because most Finds have nothing to do with names of people.   A quick translation from one set of terms to another is a very useful tool to have in your scripter‚Äôs bag of tricks.  When you're building a stack and suddenly realize that a translation would help, think of these scripts.
  134. Ô£ø
  135.  
  136. -- part contents for background part 17
  137. ----- text -----
  138. Dictionary
  139.  
  140. -- part contents for background part 18
  141. ----- text -----
  142.  
  143.  
  144.  
  145. ‚Ä¢ by
  146. Ted Kaehler
  147.  
  148. -- part contents for background part 19
  149. ----- text -----
  150. volume 1 ‚Ä¢  number  7  ‚Ä¢  card 7  ‚Ä¢